# Top-level Makefile
# 
# Targets:
#   gmake [ default ]        Compiles sources in src directory
#   gmake check              Compiles sources and runs tests.  The parameter
#                            APYC indicates which compiler to run.
#   gmake clean              Removes unnecessary files, including those that
#                            are reproducible.
#   gmake depend             Computes the dependencies between files that 
#                            gmake uses to determine when to rebuild a program,
#			     storing the result in the file .depends (see the
#			     -include directive below).

APYC = ./apyc

LEX = flex

# C++ compilation flags: produce debugging data, warn about numerous errors,
# and treat warnings as errors.
# FORCE 32 bits compilation in 64 bits systems (needs libc6-dev-i386, lib32stdc++6-4.4-dbg in Ubuntu).
CXXFLAGS = -m32 -g -Wall -Werror

GOODTEST = python tests/test-proj 

BADTEST = python tests/test-proj --errors

# List of all C++ object files
OBJS = apyc.o parser.o ast.o ast-parser.o nodes.o decls.o types.o \
       environ.o semant.o \
       assemble.o codegen.o machine-dep.o vm.o execute.o vmruntime.o

# List of all C++ sources generated by tools
GENERATED_SRCS = parser.cc lexer.cc ast-parser.cc ast-lexer.cc

.PHONY: default compile check clean really-clean depend

# How to convert Bison .y files into .cc files
%.cc: %.y
	bison -v -o $@ $<

# How to convert Flex .l files into .cc files
%.cc: %.l
	flex -o $@ $<

PHASES = 3 4

default: compile

compile: apyc

apyc: $(OBJS)
	$(CXX) -m32 -g -o $@ $(OBJS) # FORCE 32 bits

check%: compile
	@code=0; \
	echo "Testing correct programs (phase $*)..."; \
	$(GOODTEST) --stage=$* --compiler=$(APYC) tests/correct/*.py || code=1; \
	echo; \
	echo "Testing erroneous programs (phase $*)..."; \
	$(BADTEST) --stage=$* --compiler=$(APYC) tests/incorrect/*.py || code=1; \
	exit $$code

check: 
	code=0; \
	for phase in $(PHASES); do \
	    $(MAKE) check$$phase || code=1; \
	done; \
	exit $$code

clean:
	rm -f *~ *.o *.pyc *.ast *.decls *.tab.c *.output apyc OUTPUT* errflag
	rm -f read-il.cc parse-il.cc 
	rm -f tests/*/*.ast  
	rm -f tests/*~ tests/*/*~
	rm -f $(GENERATED_SRCS)

depend:
	rm -f .depends
	$(MAKE) .depends

.depends:
	touch .depends
	$(MAKE) $(GENERATED_SRCS)
	$(CXX) -m32 -MM $(OBJS:.o=.cc) > .depends

# Dependencies

parser.o: parser.cc lexer.cc apyc.h
	$(CXX) -c $(CXXFLAGS) -Wno-sign-compare -o $@ $<

ast-parser.o: ast-parser.cc ast-lexer.cc apyc.h
	$(CXX) -c $(CXXFLAGS) -Wno-sign-compare -o $@ $<

-include .depends

# Not normally used, except for testing stand-alone compilation of runtime.cc.
runtime.o: runtime.cc runtime.h vm.h
